﻿using System;
using System.Collections;
using System.Reflection;

namespace SimpleORM
{
    public static class TypeExtension
    {
        #region Methods

        #region Methods - Traversal

        public static void TraversalMethodsInfo(this Type source, Func<MethodInfo, bool> method)
        {
            if (method == null || source == null)
                return;

            MethodInfo[] list = source.GetMethods();

            foreach (MethodInfo fi in list)
            {
                if (!method(fi))
                    return;
            }
        }

        public static void TraversalPropertiesInfo(this Type source, Func<PropertyInfo, bool> method, BindingFlags? flags = null)
        {
            if (method == null || source == null)
                return;

            PropertyInfo[] listPropertyInfo = flags == null ?
                source.GetProperties() : source.GetProperties(flags.Value);

            foreach (PropertyInfo pi in listPropertyInfo)
                if (!method(pi))
                    return;
        }

        public static void TraversalBaseType(this Type source, Func<Type, bool> method)
        {
            if (method == null || source == null)
                return;

            do
            {
                if (!method(source))
                    break;

                source = source.BaseType;

            } while (source != null);
        }

        #endregion

        #region Methods - Type

        public static bool IsEnumerable(this Type source)
        {
            return IsKindOf(source, typeof(IEnumerable));
        }

        public static bool IsKindOf(this Type source, Type target)
        {
            if (source == null)
                return false;

            if (source == target)
                return true;

            if (IsKindOf(source.BaseType, target))
                return true;

            foreach (Type tpInterface in source.GetInterfaces())
                if (IsKindOf(tpInterface, target))
                    return true;

            return false;
        }

        public static object GetDefaultValue(this Type source)
        {
            if (source.IsValueType)
                return Activator.CreateInstance(source);

            return null;
        }

        public static bool IsValueTypeOrString(this Type source)
        {
            return source.IsValueType ||
                   source.IsEnum ||
                   source.IsKindOf(typeof(string));

        }

        #endregion

        #endregion
    }
}
